package com.gitee.wsl.android.search.file

import android.content.Context
import android.provider.MediaStore
import androidx.core.database.getStringOrNull
import com.gitee.wsl.android.permissions.PermissionGroup
import com.gitee.wsl.android.permissions.PermissionsManager
import com.gitee.wsl.api.SavableSearchable
import com.gitee.wsl.api.SearchableDeserializer
import com.gitee.wsl.api.SearchableSerializer
import org.json.JSONObject

internal class LocalFileSerializer : SearchableSerializer {
    override fun serialize(searchable: SavableSearchable): String {
        searchable as LocalFile
        return jsonObjectOf(
            "id" to searchable.id
        ).toString()
    }

    override val typePrefix: String
        get() = "file"
}

internal class LocalFileDeserializer(
    val context: Context,
    val permissionsManager: PermissionsManager
) : SearchableDeserializer {
    override suspend fun deserialize(serialized: String): SavableSearchable? {
        //val permissionsManager: PermissionsManager = get()
        if (!permissionsManager.checkPermissionOnce(PermissionGroup.ExternalStorage)) return null
        val json = JSONObject(serialized)
        val uri = MediaStore.Files.getContentUri("external")
        val proj = arrayOf(
            MediaStore.Files.FileColumns._ID,
            MediaStore.Files.FileColumns.SIZE,
            MediaStore.Files.FileColumns.DATA,
            MediaStore.Files.FileColumns.MIME_TYPE
        )
        val sel = "${MediaStore.Files.FileColumns._ID} = ?"
        val selArgs = arrayOf(json.getLong("id").toString())
        val cursor = context.contentResolver.query(uri, proj, sel, selArgs, null) ?: return null
        if (cursor.moveToNext()) {
            val path = cursor.getString(2)
            if (!java.io.File(path).exists()) return null
            val directory = java.io.File(path).isDirectory
            val id = cursor.getLong(0)
            val mimeType = cursor.getStringOrNull(3).takeIf { it != "application/octet-stream" }
                ?: if (directory) "resource/folder" else LocalFile.getMimetypeByFileExtension(
                    path.substringAfterLast(
                        '.'
                    )
                )
            val size = cursor.getLong(1)
            cursor.close()
            return LocalFile(
                path = path,
                mimeType = mimeType,
                size = size,
                isDirectory = directory,
                id = id,
                metaData = LocalFile.getMetaData(context, mimeType, path)
            )
        }
        cursor.close()
        return null
    }
}

fun jsonObjectOf(vararg pairs: Pair<String, Any?>): JSONObject {
    val json = JSONObject()
    for ((k, v) in pairs) {
        when (v) {
            is Float -> json.put(k, v.toDouble())
            is Double -> json.put(k, v)
            is Int -> json.put(k, v)
            is Long -> json.put(k, v)
            is Boolean -> json.put(k, v)
            is String -> json.put(k, v)
            else -> json.put(k, v)
        }
    }
    return json
}